package bold.deposit.dbsoure;

import com.alibaba.druid.util.JdbcUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 1、心跳检查
 * 2、断线重连
 * 灾备数据源 重连
 **/
@Log4j2
public class DynamicDataSource extends AbstractRoutingDataSource implements ApplicationContextAware {

    private volatile DataSource dataSource;

    DynamicDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        //什么也不用做 determineTargetDataSource 被覆盖，此方法无效
        return "do not";
    }

    @Override
    protected DataSource determineTargetDataSource() {
        return dataSource;
    }

    /**
     * 覆盖父类什么都不做
     */
    @Override
    public void afterPropertiesSet() {
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        Executors.newScheduledThreadPool(1)
//                .scheduleWithFixedDelay(new ChangeSource(dataSource), 0, 10, TimeUnit.SECONDS);
    }

    @Log4j2
    private static class ChangeSource implements Runnable {

        private DataSource dataSource;

        private ChangeSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }

        @Override
        public void run() {
            boolean check = check();
            if (check) {
                log.info("心跳检测成功");
            } else {
                log.error("心跳检测失败----");
//                if (reconnect()) {
//                    log.error("开始切换灾备成功");
//                } else {
//                    log.error("开始切换灾备失败");
//                }
            }

        }

        public boolean check() {
            String validationQuery = "SELECT 1 FROM DUAL";
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            boolean result = false;
            try {
                conn = dataSource.getConnection();
                stmt = conn.createStatement();

                rs = stmt.executeQuery(validationQuery);
                result = true;
            } catch (Exception e) {
                log.error("check db status ---------------------", e);
            } finally {
                JdbcUtils.close(rs);
                JdbcUtils.close(stmt);
                JdbcUtils.close(conn);
            }
            return result;
        }

//        private boolean reconnect() {
//            boolean isSuccess = true;
//            //难点 jdbc dns 清除缓存
//            //     重新初始化数据源 ??
//            if (dataSource instanceof DruidDataSource) {
//                DruidDataSource druid = (DruidDataSource) dataSource;
//                druid.close();
//                try {
//                    String url = "jdbc:mysql://127.0.0.1:3307/bold?useUnicode=true&characterEncoding=utf8" +
//                            "&serverTimezone=Asia/Shanghai&autoReconnect=true&zeroDateTimeBehavior=convertToNull";
//                    druid.setUrl(url);
//                    druid.init();
//                    check();
//                } catch (SQLException e) {
//                    log.error("重连失败-------", e);
//                    isSuccess = false;
//                }
//
//            } else {
//                throw new IllegalArgumentException("dataSource type,not have handle!!!!");
//            }
//            return isSuccess;
//        }
    }
}
